package com.shm.miss;

import static java.lang.Math.min;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;

import android.Manifest;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.hardware.camera2.CameraAccessException;
import android.net.Uri;
import android.opengl.GLSurfaceView;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.util.Size;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LegendEntry;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.listener.ChartTouchListener;
import com.github.mikephil.charting.listener.OnChartGestureListener;
import com.shm.miss.databinding.ActivityMainBinding;
import com.shm.singlecamera.Camera.CameraStateMachine;
import com.shm.singlecamera.Camera.ImageProcess;
import com.shm.singlecamera.Camera.SingleCamera;
import com.shm.singlecamera.UI.AssistView;
import com.shm.singlecamera.UI.WheelAdapter;
import com.shm.singlecamera.Utils.AnimUtils;
import com.shm.singlecamera.Utils.CameraRender;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    static {
        System.loadLibrary("miss");
    }

    private static native void startRecording();
    private static native void stopRecording();
    private native String[] getRecordedFolders();
    private static native void calcProjects(String[] projectsName);
    private native void passMovePath(String path);
    private native void passCalibPath(String path);
    private native void setMethods(MainActivity lineChartObject,
                                   ImageProcess imageProcess,
                                   GLSurfaceView previewObject,
                                   CameraRender renderObject);

    private native void cleanupRef();

    private ActivityMainBinding viewBinding;

    private SingleCamera camera;
    private ImageProcess imageProcess;

    private Size cameraSize;

    private ViewTreeObserver.OnGlobalLayoutListener sizeListener;

    private final Handler tickHandler = new Handler();
    private Runnable tickRunnable;

    private final int CALC_FINISH = 100;

    private final Handler mainHandler = new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(Message msg) {

            if(msg.what == CALC_FINISH){
                // 显示完成按钮
                viewBinding.control.realtimePanel.finishButton.setVisibility(View.VISIBLE);
            }

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        viewBinding = ActivityMainBinding.inflate(getLayoutInflater());

        // 隐藏状态栏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        setContentView(viewBinding.getRoot());

        // 初始化轮盘
        initView();

        // 初始化文件
        initAsset();

        // 申请权限
        verifyPermissions();
    }

    private void initAsset() {
        copyJpgFilesFromAssets();

        // 获取私有目录下的 .jpg 文件列表
        File filesDir = getFilesDir();
        File[] files = filesDir.listFiles((dir, name) -> name.endsWith(".png"));

        // 将文件路径传递给 JNI 层
        if (files != null) {
            for (File file : files) {
                if(file.getName().contains("move")){
                    passMovePath(file.getAbsolutePath());
                }
                if(file.getName().contains("calibrate")){
                    passCalibPath(file.getAbsolutePath());
                }
            }
        }

    }


    private void copyJpgFilesFromAssets() {
        AssetManager assetManager = getAssets();
        try {
            // 列出 asset 根目录下的所有文件
            String[] files = assetManager.list("");
            if (files != null) {
                for (String file : files) {
                    if (file.endsWith(".png")) {
                        // 打开 asset 文件的输入流
                        InputStream inputStream = assetManager.open(file);
                        // 创建目标文件（应用私有目录）
                        File outFile = new File(getFilesDir(), file);
                        FileOutputStream outputStream = new FileOutputStream(outFile);

                        // 读取并写入文件
                        byte[] buffer = new byte[1024];
                        int read;
                        while ((read = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, read);
                        }

                        // 关闭流
                        inputStream.close();
                        outputStream.close();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private void initView() {

        // 初始化RecyclerView
        viewBinding.control.calcPanel.fileRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        List<Integer> manualFocusDrawableList = new ArrayList<>();
        // 添加起始和结束的特定drawable资源
        int[] specialDrawables = {
                com.shm.singlecamera.R.drawable.focus0,  com.shm.singlecamera.R.drawable.focus10,
                com.shm.singlecamera.R.drawable.focus20, com.shm.singlecamera.R.drawable.focus30,
                com.shm.singlecamera.R.drawable.focus40,  com.shm.singlecamera.R.drawable.focus50,
                com.shm.singlecamera.R.drawable.focus60,  com.shm.singlecamera.R.drawable.focus70,
                com.shm.singlecamera.R.drawable.focus80,  com.shm.singlecamera.R.drawable.focus90,
                com.shm.singlecamera.R.drawable.focus100
        };
        // 如果focus_x需要在每个特定drawable之后添加4次，可以将上面的循环放到for循环中
        for (int resId : specialDrawables) {
            manualFocusDrawableList.add(resId);
            if(resId != specialDrawables[specialDrawables.length - 1]){
                for (int i = 0; i < 9; i++) {
                    manualFocusDrawableList.add( com.shm.singlecamera.R.drawable.focus_x);
                }
            }
        }

        viewBinding.manualFocusWheel.setAdapter(new WheelAdapter() {
            @SuppressLint("UseCompatLoadingForDrawables")
            @Override
            public Drawable getDrawable(int position) {
                return getResources().getDrawable(manualFocusDrawableList.get(position));
            }

            @Override
            public int getCount() {
                return manualFocusDrawableList.size();
            }
        });
        viewBinding.manualFocusWheel.setLimitation(-365.0f, 5.0f);
        viewBinding.manualFocusWheel.setOnWheelItemSelectedListener((parent, itemDrawable, position) -> {
            HardwareUtils.vibrate(getBaseContext(), 20);
            float ratio;
            if(position == 0) ratio = 0.f;
            else ratio = (float) (position + 1) / manualFocusDrawableList.size();

            camera.setFocusDistance(ratio);

            viewBinding.currentFocus.setText(String.valueOf(position));
        });
        viewBinding.manualFocusWheel.setClickable(false);
        viewBinding.manualFocusPanel.setVisibility(View.GONE);


        viewBinding.control.camera.assistView.setOnViewSelectedListener(
                new AssistView.onViewSelectedListener() {
                    @Override
                    public void select() {
                        HardwareUtils.vibrate(MainActivity.this, 20);
                        manualFocusActive();
                        manualExposureActive();
                        manualWhiteBalanceActive();
                    }

                    @Override
                    public void unselect() {
                        HardwareUtils.vibrate(MainActivity.this, 20);
                        manualFocusInactive();
                        manualExposureActive();
                        manualWhiteBalanceActive();
                    }
                });

        sizeListener = () -> {
            // 在这里获取尺寸
            int width = viewBinding.control.camera.assistView.getWidth();
            int height = viewBinding.control.camera.assistView.getHeight();
            if (width > 0 && height > 0) {
                // 这里注意是宽高相反的
                cameraSize = new Size(width, height);

                viewBinding.control.camera.assistView.getViewTreeObserver().removeOnGlobalLayoutListener(sizeListener);
            }
        };
        viewBinding.control.camera.assistView.getViewTreeObserver().addOnGlobalLayoutListener(sizeListener);

        // 关闭所有的控制面板
        closeAllPanel();

        // 显示ROI面板
//        showROIPanel();

        // 显示模板面板
        showTemplatePanel();
    }



    private void closeAllPanel(){
//        viewBinding.control.roiPanel.getRoot().setVisibility(View.GONE);
//        viewBinding.control.roiPanel.clearROIButton.setVisibility(View.VISIBLE);
//        viewBinding.control.roiPanel.selectROIPanel.setVisibility(View.GONE);
//        viewBinding.control.roiPanel.ROI1Button.setVisibility(View.VISIBLE);
//        viewBinding.control.roiPanel.ROI2Button.setVisibility(View.VISIBLE);
//        viewBinding.control.roiPanel.ROI1Button.setOnClickListener(null);
//        viewBinding.control.roiPanel.ROI2Button.setOnClickListener(null);
//        viewBinding.control.roiPanel.selectROIButton.setOnClickListener(null);
//        viewBinding.control.roiPanel.clearROIButton.setOnClickListener(null);

        viewBinding.control.templatePanel.getRoot().setVisibility(View.GONE);
        viewBinding.control.templatePanel.clearTemplateButton.setVisibility(View.VISIBLE);
        viewBinding.control.templatePanel.selectTemplatePanel.setVisibility(View.GONE);
        viewBinding.control.templatePanel.moveTemplateButton.setVisibility(View.VISIBLE);
        viewBinding.control.templatePanel.calibTemplateButton.setVisibility(View.VISIBLE);
        viewBinding.control.templatePanel.moveTemplateButton.setOnClickListener(null);
        viewBinding.control.templatePanel.calibTemplateButton.setOnClickListener(null);
        viewBinding.control.templatePanel.selectTemplateButton.setOnClickListener(null);
        viewBinding.control.templatePanel.clearTemplateButton.setOnClickListener(null);

        viewBinding.control.recordPanel.getRoot().setVisibility(View.GONE);
        viewBinding.control.recordPanel.recordButton.setOnClickListener(null);

        viewBinding.control.realtimePanel.getRoot().setVisibility(View.GONE);
        viewBinding.control.realtimePanel.finishButton.setOnClickListener(null);

        showCalcPanel();
    }

//    @SuppressLint("UseCompatLoadingForDrawables")
//    private void showROIPanel(){
//        viewBinding.control.roiPanel.getRoot().setVisibility(View.VISIBLE);
//        // 设置ROIButton事件
//        viewBinding.control.roiPanel.ROI1Button.setOnClickListener(new View.OnClickListener() {
//
//            @Override
//            public void onClick(View v) {
//                HardwareUtils.vibrate(getBaseContext(), 20);
//
//                if(!viewBinding.control.camera.assistView.isROI()){
//                    Toast.makeText(MainActivity.this, "请框选ROI", Toast.LENGTH_SHORT).show();
//                    return;
//                }
//
//                viewBinding.control.camera.assistView.setROI1();
//                viewBinding.control.roiPanel.ROI1Button.setText(R.string.roi1_selected);
//                viewBinding.control.roiPanel.ROI1Button.setBackground(getResources().
//                        getDrawable(R.drawable.roi1_button));
//
//                if(viewBinding.control.camera.assistView.isROI1() && viewBinding.control.camera.assistView.isROI2()){
//                    viewBinding.control.roiPanel.selectROIPanel.setVisibility(View.VISIBLE);
//                }
//            }
//        });
//        // 设置ROIButton事件
//        viewBinding.control.roiPanel.ROI2Button.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                HardwareUtils.vibrate(getBaseContext(), 20);
//
//                if(!viewBinding.control.camera.assistView.isROI()){
//                    Toast.makeText(MainActivity.this, "请框选ROI", Toast.LENGTH_SHORT).show();
//                    return;
//                }
//
//                viewBinding.control.camera.assistView.setROI2();
//                viewBinding.control.roiPanel.ROI2Button.setText(R.string.roi2_selected);
//                viewBinding.control.roiPanel.ROI2Button.setBackground(getResources().
//                        getDrawable(R.drawable.roi2_button));
//
//                if(viewBinding.control.camera.assistView.isROI1() && viewBinding.control.camera.assistView.isROI2()){
//                    viewBinding.control.roiPanel.selectROIPanel.setVisibility(View.VISIBLE);
//                }
//            }
//        });
//
//        viewBinding.control.roiPanel.selectROIButton.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                HardwareUtils.vibrate(getBaseContext(), 20);
//                if(viewBinding.control.camera.assistView.isROI1() &&
//                   viewBinding.control.camera.assistView.isROI2()){
//
//                    // 锁定ROI
//                    viewBinding.control.roiPanel.ROI1Button.setClickable(false);
//                    viewBinding.control.roiPanel.ROI2Button.setClickable(false);
//
//                    // 显示锁定状态
//                    viewBinding.control.camera.assistView.lockROI();
//                    viewBinding.control.roiPanel.selectROIButton.setText(R.string.selected_roi);
//                    viewBinding.control.roiPanel.selectROIButton.setBackground(getResources().
//                            getDrawable(R.drawable.selected_button));;
//
//
//                    // 锁定ROI后，显示recordPanel
//                    viewBinding.control.calcPanel.getRoot().setVisibility(View.GONE);
//                    viewBinding.control.calcPanel.calcButton.setOnClickListener(null);
//
//                    showRecordPanel();
//
//                }else{
//                    Toast.makeText(MainActivity.this, "未完全选定ROI", Toast.LENGTH_SHORT).show();
//                }
//            }
//        });
//
//        viewBinding.control.roiPanel.clearROIButton.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//
//                HardwareUtils.vibrate(getBaseContext(), 20);
//
//                // 清除已经绘制的ROI
//                viewBinding.control.camera.assistView.clearROI();
//
//                // 复原ROI按钮状态
//                viewBinding.control.roiPanel.ROI1Button.setBackground(getResources().getDrawable(R.drawable.default_button));
//                viewBinding.control.roiPanel.ROI2Button.setBackground(getResources().getDrawable(R.drawable.default_button));
//                viewBinding.control.roiPanel.ROI1Button.setText(R.string.roi1);
//                viewBinding.control.roiPanel.ROI2Button.setText(R.string.roi2);
//                viewBinding.control.roiPanel.ROI1Button.setClickable(true);
//                viewBinding.control.roiPanel.ROI2Button.setClickable(true);
//
//                // 复原锁定ROI按钮状态
//                viewBinding.control.camera.assistView.unlockROI();
//                viewBinding.control.roiPanel.selectROIPanel.setVisibility(View.GONE);
//                viewBinding.control.roiPanel.selectROIButton.setText(R.string.select_roi);
//                viewBinding.control.roiPanel.selectROIButton.setBackground(getResources().getDrawable(R.drawable.default_button));
//
//                // 关闭record面板
//                viewBinding.control.recordPanel.getRoot().setVisibility(View.GONE);
//                viewBinding.control.recordPanel.getRoot().setVisibility(View.GONE);
//                viewBinding.control.recordPanel.recordButton.setOnClickListener(null);
//            }
//        });
//
//        viewBinding.control.realtimePanel.finishButton.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                // 点击计算完成按钮，返回常态
//                viewBinding.control.realtimePanel.getRoot().setVisibility(View.GONE);
//                viewBinding.control.staticPanel.setVisibility(View.VISIBLE);
//
//                // 恢复相机功能
//                try {
//                    camera.continueCapture();
//                } catch (CameraAccessException e) {
//                    throw new RuntimeException(e);
//                }
//            }
//        });
//
//    }

    @SuppressLint("UseCompatLoadingForDrawables")
    private void showTemplatePanel(){
        viewBinding.control.templatePanel.getRoot().setVisibility(View.VISIBLE);
        // 设置移动模板事件
        viewBinding.control.templatePanel.moveTemplateButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                HardwareUtils.vibrate(getBaseContext(), 20);

                if(!viewBinding.control.camera.assistView.isTemplate()){
                    Toast.makeText(MainActivity.this, "请框选移动模板", Toast.LENGTH_SHORT).show();
                    return;
                }

                viewBinding.control.camera.assistView.setMoveTemplate();
                viewBinding.control.templatePanel.moveTemplateButton.setText(R.string.move_template_selected);
                viewBinding.control.templatePanel.moveTemplateButton.setBackground(getResources().
                        getDrawable(R.drawable.roi1_button));

                if(viewBinding.control.camera.assistView.isMoveTemplate() && viewBinding.control.camera.assistView.isCalibTemplate()){
                    viewBinding.control.templatePanel.selectTemplatePanel.setVisibility(View.VISIBLE);
                }
            }
        });
        // 设置标定模板事件
        viewBinding.control.templatePanel.calibTemplateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                HardwareUtils.vibrate(getBaseContext(), 20);

                if(!viewBinding.control.camera.assistView.isTemplate()){
                    Toast.makeText(MainActivity.this, "请框选标定模板", Toast.LENGTH_SHORT).show();
                    return;
                }

                viewBinding.control.camera.assistView.setCalibTemplate();
                viewBinding.control.templatePanel.calibTemplateButton.setText(R.string.calib_template_selected);
                viewBinding.control.templatePanel.calibTemplateButton.setBackground(getResources().
                        getDrawable(R.drawable.roi2_button));

                if(viewBinding.control.camera.assistView.isMoveTemplate() && viewBinding.control.camera.assistView.isCalibTemplate()){
                    viewBinding.control.templatePanel.selectTemplatePanel.setVisibility(View.VISIBLE);
                }
            }
        });

        viewBinding.control.templatePanel.selectTemplateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                HardwareUtils.vibrate(getBaseContext(), 20);
                if(viewBinding.control.camera.assistView.isMoveTemplate() &&
                        viewBinding.control.camera.assistView.isCalibTemplate()){

                    // 锁定模板
                    viewBinding.control.templatePanel.moveTemplateButton.setClickable(false);
                    viewBinding.control.templatePanel.calibTemplateButton.setClickable(false);

                    // 显示锁定状态
                    viewBinding.control.camera.assistView.lockTemplate();
                    viewBinding.control.templatePanel.selectTemplateButton.setText(R.string.selected_template);
                    viewBinding.control.templatePanel.selectTemplateButton.setBackground(getResources().
                            getDrawable(R.drawable.selected_button));;


                    // 锁定模板后，显示recordPanel
                    viewBinding.control.calcPanel.getRoot().setVisibility(View.GONE);
                    viewBinding.control.calcPanel.calcButton.setOnClickListener(null);

                    showRecordPanel();

                }else{
                    Toast.makeText(MainActivity.this, "未完全选定模板", Toast.LENGTH_SHORT).show();
                }
            }
        });

        viewBinding.control.templatePanel.clearTemplateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                HardwareUtils.vibrate(getBaseContext(), 20);

                // 清除已经绘制的ROI
                viewBinding.control.camera.assistView.clearTemplate();

                // 复原模板按钮状态
                viewBinding.control.templatePanel.moveTemplateButton.setBackground(getResources().getDrawable(R.drawable.default_button));
                viewBinding.control.templatePanel.calibTemplateButton.setBackground(getResources().getDrawable(R.drawable.default_button));
                viewBinding.control.templatePanel.moveTemplateButton.setText(R.string.move_template);
                viewBinding.control.templatePanel.calibTemplateButton.setText(R.string.calib_template);
                viewBinding.control.templatePanel.moveTemplateButton.setClickable(true);
                viewBinding.control.templatePanel.calibTemplateButton.setClickable(true);

                // 复原锁定模板按钮状态
                viewBinding.control.camera.assistView.unlockTemplate();
                viewBinding.control.templatePanel.selectTemplatePanel.setVisibility(View.GONE);
                viewBinding.control.templatePanel.selectTemplateButton.setText(R.string.select_template);
                viewBinding.control.templatePanel.selectTemplateButton.setBackground(getResources().getDrawable(R.drawable.default_button));

                // 关闭record面板
                viewBinding.control.recordPanel.getRoot().setVisibility(View.GONE);
                viewBinding.control.recordPanel.getRoot().setVisibility(View.GONE);
                viewBinding.control.recordPanel.recordButton.setOnClickListener(null);
            }
        });

        viewBinding.control.realtimePanel.finishButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 点击计算完成按钮，返回常态
                viewBinding.control.realtimePanel.getRoot().setVisibility(View.GONE);
                viewBinding.control.staticPanel.setVisibility(View.VISIBLE);

                // 恢复相机功能
                try {
                    camera.continueCapture();
                } catch (CameraAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        });

    }

    @SuppressLint("UseCompatLoadingForDrawables")
    private void showRecordPanel(){
        viewBinding.control.recordPanel.getRoot().setVisibility(View.VISIBLE);
        // 设置RecordButton事件
        viewBinding.control.recordPanel.recordButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                HardwareUtils.vibrate(getBaseContext(), 20);

                if(!CameraStateMachine.isRecording()){

                    viewBinding.control.recordPanel.recordButton.setBackground(getResources().
                            getDrawable(R.drawable.selected_button));
                    viewBinding.control.recordPanel.recordButton.setText(R.string.recording);
//                    viewBinding.control.roiPanel.clearROIButton.setVisibility(View.GONE);
//                    viewBinding.control.roiPanel.ROI1Button.setVisibility(View.GONE);
//                    viewBinding.control.roiPanel.ROI2Button.setVisibility(View.GONE);
                    viewBinding.control.templatePanel.clearTemplateButton.setVisibility(View.GONE);
                    viewBinding.control.templatePanel.moveTemplateButton.setVisibility(View.GONE);
                    viewBinding.control.templatePanel.calibTemplateButton.setVisibility(View.GONE);

                    viewBinding.control.recordPanel.timer.setVisibility(View.VISIBLE);
                    // 设置计时器
                    tickRunnable = new Runnable() {
                        int seconds = 0;
                        @SuppressLint("DefaultLocale")
                        @Override
                        public void run() {
                            seconds++;
                            // 更新UI，例如设置TextView显示时间
                            viewBinding.control.recordPanel.timer.setText(String.format("%02d:%02d:%02d",
                                    seconds / 3600, (seconds % 3600) / 60, (seconds % 60)));
                            tickHandler.postDelayed(this, 1000); // 每秒更新一次
                        }
                    };

                    // 开始计时
                    tickHandler.post(tickRunnable);

                    // 开始采集
                    startRecording();

                    CameraStateMachine.setIsRecording(true);

                }else{

                    viewBinding.control.recordPanel.recordButton.setBackground(getResources().
                            getDrawable(R.drawable.default_button));
                    viewBinding.control.recordPanel.recordButton.setText(R.string.record);
//                    viewBinding.control.roiPanel.clearROIButton.setVisibility(View.VISIBLE);
//                    viewBinding.control.roiPanel.ROI1Button.setVisibility(View.VISIBLE);
//                    viewBinding.control.roiPanel.ROI2Button.setVisibility(View.VISIBLE);
                    viewBinding.control.templatePanel.clearTemplateButton.setVisibility(View.VISIBLE);
                    viewBinding.control.templatePanel.moveTemplateButton.setVisibility(View.VISIBLE);
                    viewBinding.control.templatePanel.calibTemplateButton.setVisibility(View.VISIBLE);

                    viewBinding.control.recordPanel.timer.setVisibility(View.GONE);

                    // 停止计时
                    tickHandler.removeCallbacks(tickRunnable);

                    CameraStateMachine.setIsRecording(false);

                    // 停止采集
                    stopRecording();

                    // 停止采集后，显示计算界面
                    showCalcPanel();
                }
            }
        });
    }

    private void showCalcPanel(){

        // 获取所有的记录项目，添加到view中
        String[] folders = getRecordedFolders();
        List<FileItem> fileItems = new ArrayList<>();

        for(String folder: folders){
            fileItems.add(new FileItem(folder));
        }
        // 设置适配器
        // 选中状态更新时处理
        FileAdapter adapter = new FileAdapter(fileItems, new FileAdapter.OnCheckChangedListener() {
            @Override
            public void onCheckChanged(int position, boolean isChecked) {
                // 选中状态更新时处理
                fileItems.get(position).setChecked(isChecked);
            }
        });
        viewBinding.control.calcPanel.fileRecyclerView.setAdapter(adapter);

        viewBinding.control.calcPanel.getRoot().setVisibility(View.VISIBLE);
        viewBinding.control.calcPanel.calcButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                HardwareUtils.vibrate(getBaseContext(), 20);

                // 停止相机功能
                try {
                    camera.pauseCapture();
                } catch (CameraAccessException e) {
                    throw new RuntimeException(e);
                }

                // 根据在线/离线功能设置相机连接状态提示文字
                // 这里暂时先这样，未来可能替换为更细节的区分逻辑
                if(viewBinding.control.camera.assistView.isMoveTemplate() && viewBinding.control.camera.assistView.isCalibTemplate()){
                    viewBinding.control.cameraStatus.setText(R.string.connected_camera);
                }else{
                    viewBinding.control.cameraStatus.setText(R.string.unconnected_camera);
                }

                // 进入实时显示阶段，隐藏静态界面，显示动态界面
                viewBinding.control.staticPanel.setVisibility(View.GONE);
                viewBinding.control.realtimePanel.getRoot().setVisibility(View.VISIBLE);
                viewBinding.control.realtimePanel.finishButton.setVisibility(View.GONE);

                // 开启子线程计算
                new Thread(new Runnable() {
                    @Override
                    public void run() {

                        List<String> selected = new ArrayList<>();
                        for (FileItem item : fileItems) {
                            if (item.isChecked()) {
                                selected.add(item.getName());
                            }
                        }
                        String[] selectedProjects = selected.toArray(new String[0]);

                        // 批量计算
                        calcProjects( selectedProjects);

                        Message message = mainHandler.obtainMessage();
                        message.what = CALC_FINISH;
                        mainHandler.sendMessage(message);
                    }
                }).start();
            }
        });

    }

    public synchronized void initLineChart() {
        LineChart lineChart = viewBinding.control.realtimePanel.lineChart;

        //设置表样式
        //绘制区域边框、设置边框颜色、边框宽度
        lineChart.setDrawBorders(true);
        lineChart.setBorderColor(Color.WHITE);
        lineChart.getAxisRight().setEnabled(false);
        lineChart.setBorderWidth(2);

        //滑动触摸相关
        lineChart.setTouchEnabled(true); // 所有触摸事件,默认true
        lineChart.setDragEnabled(true);    // 可拖动,默认true
        lineChart.setScaleEnabled(true);   // 两个轴上的缩放,X,Y分别默认为true
        lineChart.setScaleXEnabled(true);  // X轴上的缩放,默认true
        lineChart.setScaleYEnabled(true);  // Y轴上的缩放,默认true
        lineChart.setPinchZoom(true);  // X,Y轴同时缩放，false则X,Y轴单独缩放,默认false
        lineChart.setDoubleTapToZoomEnabled(true); // 双击缩放,默认true
        lineChart.setDragDecelerationEnabled(true);    // 抬起手指，继续滑动,默认true
        lineChart.setDragDecelerationFrictionCoef(0.9f);   // 摩擦系数,[0-1]，较大值速度会缓慢下降，0，立即停止;1,无效值，并转换为0.9999.默认0.9f.
        lineChart.setOnChartGestureListener (new OnChartGestureListener() { // 手势监听器
            @Override
            public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
                // 按下
            }

            @Override
            public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
                // 抬起,取消
            }

            @Override
            public void onChartLongPressed(MotionEvent me) {
                // 长按
            }

            @Override
            public void onChartDoubleTapped(MotionEvent me) {
                // 双击
            }

            @Override
            public void onChartSingleTapped(MotionEvent me) {
                // 单击
            }

            @Override
            public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
                // 甩动
            }

            @Override
            public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
                // 缩放
            }

            @Override
            public void onChartTranslate(MotionEvent me, float dX, float dY) {
                // 移动
            }
        });

        //轴相关
        // 由四个元素组成：
        // 标签：即刻度值。也可以自定义，比如时间，距离等等，下面会说一下；
        // 轴线：坐标轴；
        // 网格线：垂直于轴线对应每个值画的轴线；
        // 限制线：最值等线。
        XAxis xAxis = lineChart.getXAxis();    // 获取X轴
        xAxis.setAxisLineColor(Color.WHITE); // 坐标轴颜色，默认GRAY
        xAxis.setTextColor(Color.WHITE); //刻度文字颜色
        xAxis.setGridColor(Color.WHITE);   // 网格线颜色，默认GRAY
        xAxis.setTextSize(10f);
        xAxis.setGridLineWidth(1); // 网格线宽度，dp，默认1dp
        xAxis.setAxisLineWidth(2);
        xAxis.setPosition(XAxis.XAxisPosition.TOP);
        xAxis.enableGridDashedLine(20, 10, 1);

        YAxis yAxis = lineChart.getAxisLeft(); // 获取Y轴,mLineChart.getAxis(YAxis.AxisDependency.LEFT);也可以获取Y轴
        yAxis.setTextColor(Color.WHITE);  // 标签字体颜色
        yAxis.setTextSize(10f);    // 标签字体大小，dp，6-24之间，默认为10dp
        yAxis.setGridColor(Color.WHITE);    // 网格线颜色，默认GRAY
        yAxis.setGridLineWidth(1f);    // 网格线宽度，dp，默认1dp
        yAxis.setAxisLineColor(Color.WHITE);  // 坐标轴颜色，默认GRAY.测试到一个bug，假如左侧线只有1dp，
        yAxis.setAxisLineWidth(2f);  // 坐标轴线宽度，dp，默认1dp
        yAxis.setAxisMaximum(0.1f);
        yAxis.setAxisMinimum(0.f);
        yAxis.enableGridDashedLine(20, 10, 1);
        // 网格线为虚线，lineLength，每段实线长度,spaceLength,虚线间隔长度，phase，起始点（进过测试，最后这个参数也没看出来干啥的）

        //图例相关
        Legend legend = lineChart.getLegend(); // 获取图例，但是在数据设置给chart之前是不可获取的
        legend.setEnabled(true);    // 是否绘制图例
        legend.setTextColor(Color.WHITE);    // 图例标签字体颜色，默认BLACK
        legend.setTextSize(10); // 图例标签字体大小[6,24]dp,默认10dp
        legend.setTypeface(null);   // 图例标签字体
        legend.setWordWrapEnabled(false);    // 当图例超出时是否换行适配，这个配置会降低性能，且只有图例在底部时才可以适配。默认false
        legend.setMaxSizePercent(1f); // 设置，默认0.95f,图例最大尺寸区域占图表区域之外的比例
        legend.setForm(Legend.LegendForm.SQUARE);   // 设置图例的形状，SQUARE, CIRCLE 或者 LINE
        legend.setXEntrySpace(6);  // 设置水平图例间间距，默认6dp
        legend.setYEntrySpace(0);  // 设置垂直图例间间距，默认0
        legend.setDrawInside(true);
        legend.setFormToTextSpace(5);    // 设置图例的标签与图形之间的距离，默认5dp

        LegendEntry strain = new LegendEntry("strain", Legend.LegendForm.LINE,
                10f, 2f, null, Color.RED);
        List<LegendEntry> entries = new ArrayList<>();
        entries.add(strain);

        legend.setCustom(entries);

        // 重置数据
        values = new ArrayList<>();
        maxVal = Float.MIN_VALUE;
        minVal = Float.MAX_VALUE;

        lineChart.invalidate();
    }

    private ArrayList<Entry> values;
    private float maxVal, minVal;

    public synchronized void setLineChartData(double data) {

        float dataF = (float) data;

        maxVal = Math.max(maxVal, dataF);
        minVal = Math.min(minVal, dataF);

        // 使用add()而不是set()
        values.add(new Entry(values.size(), dataF));

        // 防止更新太快卡死
        if(values.size() % 5 != 0) return;

        LineData lineData = viewBinding.control.realtimePanel.lineChart.getData();

        if (lineData == null) {
            LineDataSet set = new LineDataSet(values, "strain");
            setLineDataSet(set);

            ArrayList<ILineDataSet> dataSets = new ArrayList<>();
            dataSets.add(set);

            lineData = new LineData(dataSets);
            viewBinding.control.realtimePanel.lineChart.setData(lineData);
        } else {
            // 更新现有数据集
            LineDataSet set = (LineDataSet) lineData.getDataSetByIndex(0);
            set.setValues(values);  // 更新数据集的值
            setLineDataSet(set);

            lineData.notifyDataChanged();
            viewBinding.control.realtimePanel.lineChart.notifyDataSetChanged();
        }

        YAxis yAxis = viewBinding.control.realtimePanel.lineChart.getAxisLeft();
        float maxY = yAxis.getAxisMaximum();
        float minY = yAxis.getAxisMinimum();

        float nExpend = 0.05f;

        if (maxY == 0 || minY == 0) {
            yAxis.setAxisMaximum(maxVal + nExpend);
            yAxis.setAxisMinimum(minVal - nExpend);
        } else {
            if (maxY < maxVal)
                yAxis.setAxisMaximum(maxVal + nExpend);
            if (minY > minVal)
                yAxis.setAxisMinimum(minVal - nExpend);
        }

        viewBinding.control.realtimePanel.lineChart.postInvalidate();
    }


    private static void setLineDataSet(LineDataSet set) {
        set.setValueTextSize(3f);
        set.setColor(Color.RED);
        set.setValueTextColor(Color.RED);
        set.setCircleColor(Color.RED);
        set.setLineWidth(3f);
        set.setCircleRadius(1f);

        set.notifyDataSetChanged();
    }

    private static final int REQUEST_CODE = 1024;

    private boolean verifyPermissions() {
        List<String> permissionsNeeded = new ArrayList<>();

        // 处理存储权限（分版本策略）
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // Android 11+ 需要特殊处理
            if (!Environment.isExternalStorageManager()) {
                try {
                    Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                    startActivity(intent);
                } catch (Exception e) {
                    Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                    intent.setData(Uri.parse("package:" + getPackageName()));
                    startActivity(intent);
                }
                return false;
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // Android 10 使用作用域存储，不需要权限声明
            // 但如果要访问媒体文件需要请求
            if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                permissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
            }
        } else {
            // Android 9及以下需要传统权限
            if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                permissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            }
        }

        // 添加相机权限
        if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            permissionsNeeded.add(Manifest.permission.CAMERA);
        }

        if (!permissionsNeeded.isEmpty()) {
            requestPermissions(permissionsNeeded.toArray(new String[0]), REQUEST_CODE);
            return false;
        }
        return true;
    }

    @Override
    protected void onStart() {
        super.onStart();

    }

    private void initialCam() {

        if(imageProcess == null){
            // 获取支持的相机数量
            imageProcess = new ImageProcess(
                    this,
                    viewBinding.control.camera.cameraView,
                    viewBinding.control.camera.assistView,
                    viewBinding.control.frameSize,
                    viewBinding.control.inferenceTime);
        }


        if(camera == null){
            camera = new SingleCamera(this,
                    viewBinding.control.camera.cameraView,
                    (size, cameraRotation) -> {

                        // 相机连接成功
                        viewBinding.control.cameraStatus.setTextColor(Color.GREEN);
                        viewBinding.control.cameraStatus.setText(R.string.connected_camera);
                        viewBinding.control.frameSize.setVisibility(View.VISIBLE);
                        viewBinding.control.frameSize.setTextColor(Color.GREEN);
                        viewBinding.control.inferenceTime.setVisibility(View.VISIBLE);
                        viewBinding.control.inferenceTime.setTextColor(Color.GREEN);
                        viewBinding.control.camera.assistView.cameraConnected();

                    },
                    imageProcess);

            // 初始化绑定主摄
            CameraStateMachine.readSupportCam(this);
            camera.setLogicalCamera(CameraStateMachine.getLogicalCam());
            camera.setPhysicalCamera(CameraStateMachine.getNormalCam());
        }

        setMethods(this, imageProcess, imageProcess.getView(), imageProcess.getRender());

    }

    private void openCamera(){

        // 初始化
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                initialCam();
            }
        });

        if(cameraSize == null){

            sizeListener = () -> {
                // 在这里获取尺寸
                int width = min(viewBinding.control.camera.assistView.getWidth(), 1920);
                int height = min(viewBinding.control.camera.assistView.getHeight(), 1080);
                if (width > 0 && height > 0) {
                    // 这里注意是宽高相反的
                    cameraSize = new Size(width, height);
                    camera.openCamera(cameraSize, () -> {

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Log.d(TAG, "camera firstly opened");
                            }
                        });
                    });

                    viewBinding.control.camera.assistView.
                            getViewTreeObserver().removeOnGlobalLayoutListener(sizeListener);
                }
            };
            viewBinding.control.camera.assistView.
                    getViewTreeObserver().addOnGlobalLayoutListener(sizeListener);

        }else{
            camera.openCamera(cameraSize, () -> {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Log.d(TAG, "camera firstly opened");
                    }
                });
            });
        }

    }

    private void closeCamera(){

        camera.closeCamera(() -> {
            imageProcess.shutdown();
            imageProcess = null;

            // 相机连接成功
            viewBinding.control.cameraStatus.setTextColor(Color.RED);
            viewBinding.control.cameraStatus.setText(R.string.unconnected_camera);
            viewBinding.control.frameSize.setVisibility(View.INVISIBLE);
            viewBinding.control.inferenceTime.setVisibility(View.INVISIBLE);
            viewBinding.control.camera.assistView.cameraUnconnected();

            Log.d(TAG, "camera finally closed");
        });

    }

    @Override
    protected void onResume() {
        super.onResume();
        if(verifyPermissions()){
            openCamera();
        }else{
            Toast.makeText(this, "权限不足！", Toast.LENGTH_SHORT).show();
            finish();
        }
        viewBinding.control.camera.cameraView.onResume();

    }

    @Override
    protected void onPause() {
        super.onPause();

        viewBinding.control.camera.cameraView.onPause();
        closeCamera();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        // 清理引用问题
        cleanupRef();
        super.onDestroy();
    }

    @SuppressLint("UseCompatLoadingForDrawables")
    private void manualFocusActive() {

        viewBinding.control.controlPanel.setVisibility(View.GONE);

        viewBinding.manualFocusPanel.setVisibility(View.VISIBLE);
        AnimUtils.wheelRotateIn(viewBinding.manualFocusPanel).addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                viewBinding.manualFocusWheel.setClickable(true);
            }
        });

    }

    @SuppressLint("UseCompatLoadingForDrawables")
    private void manualFocusInactive() {

        viewBinding.manualFocusWheel.setClickable(false);
        AnimUtils.wheelRotateOut(viewBinding.manualFocusPanel).addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                viewBinding.manualFocusPanel.setVisibility(View.GONE);
                viewBinding.control.controlPanel.setVisibility(View.VISIBLE);
            }
        });

    }


    @SuppressLint("UseCompatLoadingForDrawables")
    private void manualExposureActive() {
        CameraStateMachine.setIsAELocked(true);

        camera.lockAE();
    }

    @SuppressLint("UseCompatLoadingForDrawables")
    private void manualExposureInactive() {
        CameraStateMachine.setIsAELocked(false);

        camera.unlockAE();

    }

    @SuppressLint("UseCompatLoadingForDrawables")
    private void manualWhiteBalanceActive() {
        CameraStateMachine.setIsAWBLocked(true);

        camera.lockAWB();

    }


    @SuppressLint("UseCompatLoadingForDrawables")
    private void manualWhiteBalanceInactive() {
        CameraStateMachine.setIsAWBLocked(false);

        camera.unlockAWB();

    }

}